﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using Surveying;
using Point = Surveying.Point;

namespace GIS_SpatialAnalyst
{
    class PolygonClipClass
    {
        private Polygon m_InputPolygon;
        //public Polygon m_InputPolyLine;
        private PolyLine m_InputPolyLine;
        public List<Line> m_RetainLines;//保留的线
        public List<Point> m_RetainPoints;//保留的顶点
        private PictureBox picDP;
        private Bitmap bitmap;
        private Graphics grp;
        List<Intersection> intersections = new List<Intersection>();
        public PolygonClipClass(PictureBox pictureBox,Graphics grp, Bitmap bitmap)
        {
            this.picDP = pictureBox;
            this.grp = grp;
            this.bitmap = bitmap;
        }
        class Intersection
        {
            public int id;
            public Point point;
            public Intersection(int x,Point point)
            {
                this.id = x;
                this.point = point;
            }
        }
        public void Clip(Polygon polygon, PolyLine polyline)
        {
            m_InputPolygon = polygon;
            m_InputPolyLine = polyline;
            //交点
            //组成折线的线段
            List<Line> plList = new List<Line>();
            //组成多边形的线段
            List<Line> pgList = new List<Line>();
            //折线拆分为线段
            for (int i = 0; i < m_InputPolyLine.point.Length - 1; i++)
            {
                Point[] point = new Point[2];
                point[0] = m_InputPolyLine.point[i];
                point[1] = m_InputPolyLine.point[i + 1];
                plList.Add(new Line(point[0], point[1]));
            }
            //多边形拆分为线段
            for (int i = 0; i < m_InputPolygon.points.Length; i++)
            {
                if (i == m_InputPolygon.points.Length - 1)
                {
                    Point[] point = new Point[2];
                    point[0] = m_InputPolygon.points[i];
                    point[1] = m_InputPolygon.points[0];
                    pgList.Add(new Line(point[0], point[1]));
                }
                else
                {
                    Point[] point = new Point[2];
                    point[0] = m_InputPolygon.points[i];
                    point[1] = m_InputPolygon.points[i + 1];
                    pgList.Add(new Line(point[0], point[1]));
                }
            }
            //int k;
            //i 表示折线的第几条线段
            for (int i = 0; i < plList.Count; i++)
            {
                //k表示那条线段上的点
                //k = 0;
                for (int j = 0; j < pgList.Count; j++)
                {
                    if (Line_Line_RelationClass.Line_Line_Relation(plList[i], pgList[j]))
                    {
                        //如果两条线相交求交点
                        Point p = Line_Line_RelationClass.GetIntersection(plList[i], pgList[j]);
                        p.intersection = true;
                        //k记录是那条线段上的点
                        //k = i + 1;
                        intersections.Add(new Intersection(i,p));
                    }
                }
            }
            List<Point> addpoints = AddPoint(m_InputPolyLine.point, intersections);
            JudgePoints(addpoints);
            DrawNewlines(addpoints);


        }


        private void DrawNewlines(List<Point> addpoints)
        {
            if (addpoints[0].whetherIn==false)
            {
                bool IsDraw = false;
                for (int i = 1; i < addpoints.Count - 1; i++)
                {
                    if (addpoints[i].intersection==true)
                    {
                        IsDraw = !IsDraw;
                    }
                    if (IsDraw)
                    {
                        grp.DrawLine(new Pen(Color.Red, 5), Convert.ToSingle(addpoints[i].x), Convert.ToSingle(picDP.Height - addpoints[i].y), Convert.ToSingle(addpoints[i + 1].x), Convert.ToSingle(picDP.Height - addpoints[i + 1].y));
                    }
                }
            }
            else
            {
                bool IsDraw = true;
                for (int i = 0; i < addpoints.Count - 1; i++)
                {
                    if (addpoints[i].intersection == true)
                    {
                        IsDraw = !IsDraw;
                    }
                    if (IsDraw)
                    {
                        grp.DrawLine(new Pen(Color.Red, 5), Convert.ToSingle(addpoints[i].x), Convert.ToSingle(picDP.Height - addpoints[i].y), Convert.ToSingle(addpoints[i + 1].x), Convert.ToSingle(picDP.Height - addpoints[i + 1].y));
                    }

                }
            }
            this.picDP.Image = bitmap;
        }


        /// <summary>
        /// 判断里面的点在多边形的外面还是在里面
        /// </summary>
        /// <param name="points"></param>
        private void JudgePoints(List<Point> points)
        {
            foreach (var item in points)
            {
                if (Point_PolygonClass.PointInFences(item, m_InputPolygon))
                {
                    //points.Remove(item);
                    item.whetherIn=true;
                }
            }
        }

        /// <summary>
        /// 将交点加入到折线段点集合中,且不改变有序性
        /// </summary>
        /// <param name="linepoints"></param>
        /// <param name="intersections"></param>
        /// <returns></returns>

        private List<Point> AddPoint(Point[] linepoints, List<Intersection> intersections)
        {
            List<Point> result = new List<Point>();
            for (int i = 0; i < linepoints.Length; i++)
            {
                List<Point>tempList=new List<Point>();
                result.Add(linepoints[i]);
                foreach (var item in intersections)
                {
                    //判断是那条线上的交点
                    if (i==item.id)
                    {
                        item.point.disFromOrigin = item.point.Distance(linepoints[i]);
                        tempList.Add(item.point);
                    }
                }
                //将集合中的点按照距离第一个点的距离排序
                tempList.Sort();
                result.AddRange(tempList);
            }
            return result;
        }

    }
}
